<template>
  <div class="device-manager">
    <!-- 设备列表面板 -->
    <div class="device-panel" :class="{ collapsed: panelCollapsed }">
      <div class="panel-header">
        <h3>农机设备</h3>
        <button class="collapse-btn" @click="togglePanel">
          {{ panelCollapsed ? '展开' : '收起' }}
        </button>
      </div>
      
      <div class="panel-content" v-if="!panelCollapsed">
        <!-- 设备状态过滤 -->
        <div class="filter-section">
          <label>状态过滤：</label>
          <select v-model="statusFilter" @change="filterDevices">
            <option value="">全部</option>
            <option value="WORKING">工作中</option>
            <option value="IDLE">空闲</option>
            <option value="OFFLINE">离线</option>
          </select>
          <button @click="refreshDevices" class="refresh-btn">刷新</button>
        </div>
        
        <!-- 设备列表 -->
        <div class="device-list">
          <div 
            v-for="device in filteredDevices" 
            :key="device.id"
            class="device-item"
            :class="{ selected: selectedDeviceId === device.id }"
            @click="selectDevice(device)"
          >
            <div class="device-info">
              <div class="device-name">{{ device.deviceName }}</div>
              <div class="device-type">{{ device.deviceType }}</div>
              <div class="device-status" :class="(device.status || '').toLowerCase()">
                {{ formatStatus(device.status) }}
              </div>
              <div class="device-time">
                更新时间: {{ formatTime(device.lastUpdateTime) }}
              </div>
            </div>
            <div class="device-actions">
              <button @click.stop="flyToDevice(device)" class="action-btn">
                定位
              </button>
              <button @click.stop="showDevicePaths(device)" class="action-btn">
                轨迹
              </button>
            </div>
          </div>
        </div>
      </div>
    </div>
    
    <!-- 轨迹播放控制面板 -->
    <div class="track-control" v-if="showTrackControls">
      <div class="control-header">
        <h4>轨迹播放 - {{ selectedDevice?.deviceName }}</h4>
        <button @click="closeTrackControls" class="close-btn">×</button>
      </div>
      
      <div class="control-content">
        <div class="time-range">
          <div class="time-inputs">
            <label>开始时间：</label>
            <input type="datetime-local" v-model="trackStartTime" />
            <label>结束时间：</label>
            <input type="datetime-local" v-model="trackEndTime" />
          </div>
          <div class="time-actions">
            <button @click="resetToToday" class="reset-btn">重置为今天</button>
            <button @click="queryTracks" class="query-btn">查询轨迹</button>
          </div>
        </div>
        
        <div class="track-list" v-if="deviceTracks.length > 0">
          <!-- 单日轨迹显示 -->
          <template v-if="!isMultiDayQuery">
            <div 
              v-for="track in deviceTracks" 
              :key="track.id"
              class="track-item"
              @click="selectTrack(track)"
              :class="{ selected: selectedTrackId === track.id }"
            >
              <div class="track-name">{{ track.pathName || '轨迹' + track.id }}</div>
              <div class="track-info">
                <span>距离: {{ formatDistance(track.totalDistance) }}</span>
                <span>速度: {{ formatSpeed(track.totalDistance, track.totalDuration) }}</span>
                <span>面积：{{ formatArea(track.totalArea) }}</span>
                <span>时长: {{ formatDuration(track.startTime, track.endTime) }}</span>
              </div>
            </div>
          </template>
          
          <!-- 多日轨迹分组显示 -->
          <template v-else>
            <div v-if="Object.keys(groupedTracksByDate).length === 0" class="no-tracks-message">
              选定时间范围内没有轨迹数据
            </div>
            <div v-for="(dayGroup, date) in groupedTracksByDate" :key="date" class="day-group">
              <div class="day-header" @click="toggleDayGroup(date)" :class="{ expanded: expandedDays.has(date) }">
                <span class="date-label">{{ formatDateLabel(date) }}</span>
                <span class="track-count">({{ dayGroup.length }}条轨迹)</span>
                <span class="expand-icon">{{ expandedDays.has(date) ? '▼' : '▶' }}</span>
              </div>
              
              <div v-show="expandedDays.has(date)" class="day-tracks">
                <div 
                  v-for="track in dayGroup" 
                  :key="track.id"
                  class="track-item"
                  @click="selectTrack(track)"
                  :class="{ selected: selectedTrackId === track.id }"
                >
                  <div class="track-name">{{ track.pathName || formatTrackTime(track.startTime) }}</div>
                  <div class="track-info">
                    <span>距离: {{ formatDistance(track.totalDistance) }}</span>
                    <span>速度: {{ formatSpeed(track.totalDistance, track.totalDuration) }}</span>
                    <span>面积：{{ formatArea(track.totalArea) }}</span>
                    <span>时长: {{ formatDuration(track.startTime, track.endTime) }}</span>
                  </div>
                </div>
              </div>
            </div>
          </template>
        </div>
        
        <!-- 无轨迹数据提示 -->
        <div v-else class="no-tracks-message">
          没有找到轨迹数据，请检查时间范围或刷新数据
        </div>
        
        <div class="play-controls" v-if="selectedTrack">
          <button @click="playTrack" class="play-btn" :disabled="isPlaying">
            {{ isPlaying ? '播放中...' : '播放轨迹' }}
          </button>
          <button @click="stopTrack" class="stop-btn">停止</button>
          <label>
            <input type="checkbox" v-model="loopPlay" /> 循环播放
          </label>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, reactive, onMounted, computed } from 'vue';
import { deviceAPI, pathAPI } from '../services/api.js';
import { DataUtils, SpatialUtils } from '../utils/dataUtils.js';
import * as Cesium from 'cesium';

// Props
const props = defineProps({
  viewer: {
    type: Object,
    required: true
  }
});

// Reactive data
const devices = ref([]);
const filteredDevices = ref([]);
const statusFilter = ref('');
const selectedDeviceId = ref(null);
const selectedDevice = ref(null);
const panelCollapsed = ref(false);

// 轨迹相关
const showTrackControls = ref(false);
const deviceTracks = ref([]);
const selectedTrackId = ref(null);
const selectedTrack = ref(null);

// 初始化默认时间范围
const initDefaultTimeRange = () => {
  const today = new Date();
  const year = today.getFullYear();
  const month = String(today.getMonth() + 1).padStart(2, '0');
  const day = String(today.getDate()).padStart(2, '0');
  
  return {
    start: `${year}-${month}-${day}T06:00`,
    end: `${year}-${month}-${day}T22:00`
  };
};

const defaultTimes = initDefaultTimeRange();
const trackStartTime = ref(defaultTimes.start);
const trackEndTime = ref(defaultTimes.end);
const isPlaying = ref(false);
const loopPlay = ref(false);

// 多日轨迹分组相关
const expandedDays = ref(new Set());
const isMultiDayQuery = ref(false);
const groupedTracksByDate = ref({});

// 存储设备实体引用
const deviceEntities = new Map();
let currentTrackEntity = null;
const trackPathEntities = [];
let workingAreaEntity = null;

// Computed
const formatStatus = (status) => DataUtils.formatDeviceStatus(status);
const formatTime = (time) => DataUtils.formatDateTime(time);
const formatDistance = (distance) => DataUtils.formatDistance(distance || 0);
const formatDuration = (start, end) => {
  if (!start || !end) return '';
  const diff = new Date(end) - new Date(start);
  const hours = Math.floor(diff / (1000 * 60 * 60));
  const minutes = Math.floor((diff % (1000 * 60 * 60)) / (1000 * 60));
  return `${hours}时${minutes}分`;
};

// 新增格式化方法
const formatSpeed = (distance, duration) => {
  if (!distance || !duration || duration === 0) return '0 km/h';
  const speed = (distance / 1000) / (duration / 3600); // 转换为 km/h
  return `${speed.toFixed(1)} km/h`;
};

const formatArea = (area) => {
  if (!area || area === 0) return '0 平方米';
  if (area >= 10000) {
    return `${(area / 10000).toFixed(2)} 公顷`;
  }
  return `${area.toFixed(1)} 平方米`;
};

// 日期格式化方法
const formatDateLabel = (dateStr) => {
  const date = new Date(dateStr);
  const month = date.getMonth() + 1;
  const day = date.getDate();
  const weekdays = ['日', '一', '二', '三', '四', '五', '六'];
  const weekday = weekdays[date.getDay()];
  return `${month}月${day}日 周${weekday}`;
};

const formatTrackTime = (timeStr) => {
  if (!timeStr) return '轨迹';
  const date = new Date(timeStr);
  const hours = String(date.getHours()).padStart(2, '0');
  const minutes = String(date.getMinutes()).padStart(2, '0');
  return `${hours}:${minutes} 轨迹`;
};

// 切换日期组展开/折叠
const toggleDayGroup = (date) => {
  if (expandedDays.value.has(date)) {
    expandedDays.value.delete(date);
  } else {
    expandedDays.value.add(date);
  }
};

// Methods
const togglePanel = () => {
  panelCollapsed.value = !panelCollapsed.value;
};

const refreshDevices = async () => {
  try {
    const deviceData = await deviceAPI.getAllDevices();
    // 确保数据的安全性
    devices.value = (deviceData || []).map(device => ({
      ...device,
      status: device.status || 'OFFLINE',
      deviceName: device.deviceName || '未知设备',
      deviceType: device.deviceType || 'UNKNOWN'
    }));
    filterDevices();
    updateDeviceEntities();
  } catch (error) {
    console.error('获取设备列表失败:', error);
    // 设置默认空数据，避免渲染错误
    devices.value = [];
    filteredDevices.value = [];
  }
};

const filterDevices = () => {
  if (!statusFilter.value) {
    filteredDevices.value = devices.value;
  } else {
    filteredDevices.value = devices.value.filter(device => 
      device.status === statusFilter.value
    );
  }
};

const selectDevice = (device) => {
  selectedDeviceId.value = device.id;
  selectedDevice.value = device;
};

const flyToDevice = (device) => {
  if (!device.currentPosition) return;
  
  const position = DataUtils.pointToCartesian3(device.currentPosition);
  if (position) {
    props.viewer.camera.flyTo({
      destination: Cesium.Cartesian3.fromDegrees(
        device.currentPosition.x,
        device.currentPosition.y,
        1000
      ),
      duration: 2.0
    });
  }
};

const showDevicePaths = async (device) => {
  selectedDevice.value = device;
  
  // 如果是首次打开轨迹面板，才设置默认时间范围
  if (!showTrackControls.value) {
    const times = initDefaultTimeRange();
    trackStartTime.value = times.start;
    trackEndTime.value = times.end;
  }
  
  showTrackControls.value = true;
  
  await queryTracks();
};

const closeTrackControls = () => {
  showTrackControls.value = false;
  deviceTracks.value = [];
  selectedTrack.value = null;
  selectedTrackId.value = null;
  groupedTracksByDate.value = {};
  expandedDays.value.clear();
  stopTrack();
  clearTrackDisplay();
  // 注意：不重置 trackStartTime 和 trackEndTime，保留用户选择的时间范围
};

// 重置时间范围为今天
const resetToToday = () => {
  const times = initDefaultTimeRange();
  trackStartTime.value = times.start;
  trackEndTime.value = times.end;
};

const queryTracks = async () => {
  if (!selectedDevice.value) return;
  
  try {
    const startTime = new Date(trackStartTime.value).toISOString();
    const endTime = new Date(trackEndTime.value).toISOString();
    
    console.log('查询轨迹参数:', {
      设备ID: selectedDevice.value.id,
      设备名称: selectedDevice.value.deviceName,
      开始时间: startTime,
      结束时间: endTime
    });
    
    // 判断是否为多日查询
    const startDate = new Date(trackStartTime.value);
    const endDate = new Date(trackEndTime.value);
    const daysDiff = Math.ceil((endDate - startDate) / (1000 * 60 * 60 * 24));
    isMultiDayQuery.value = daysDiff > 1;
    
    console.log('查询类型:', isMultiDayQuery.value ? '多日查询' : '单日查询', '天数差:', daysDiff);
    
    const tracks = await pathAPI.getPathsByDeviceAndTimeRange(
      selectedDevice.value.id,
      startTime,
      endTime
    );
    
    console.log('获取到轨迹数据:', tracks);
    
    // 过滤有效轨迹并为每条轨迹计算统计数据
    deviceTracks.value = (tracks || []).filter(track => {
      // 过滤掉无效的轨迹
      return track && track.pathPoints && track.pathPoints.length > 0;
    }).map(track => {
      const calculatedData = calculateTrackStatistics(track);
      return {
        ...track,
        totalDistance: calculatedData.totalDistance,
        totalDuration: calculatedData.totalDuration,
        totalArea: calculatedData.totalArea
      };
    });
    
    console.log('处理后轨迹数据:', deviceTracks.value);
    
    // 如果是多日查询，按日期分组
    if (isMultiDayQuery.value) {
      groupTracksByDate();
    }
    
    // 在地图上显示所有轨迹路径
    displayTracksOnMap();
    
  } catch (error) {
    console.error('查询轨迹失败:', error);
    // 清空数据
    deviceTracks.value = [];
    groupedTracksByDate.value = {};
  }
};

// 按日期分组轨迹
const groupTracksByDate = () => {
  const grouped = {};
  expandedDays.value.clear();
  
  // 过滤有效轨迹并分组
  deviceTracks.value.forEach(track => {
    // 检查轨迹是否有效（有开始时间且有轨迹点）
    if (!track.startTime || !track.pathPoints || track.pathPoints.length === 0) {
      console.warn('跳过无效轨迹:', track);
      return;
    }
    
    // 获取日期部分（YYYY-MM-DD）
    const dateKey = track.startTime.split('T')[0];
    
    if (!grouped[dateKey]) {
      grouped[dateKey] = [];
    }
    grouped[dateKey].push(track);
  });
  
  // 过滤掉空的日期组
  const filteredGrouped = {};
  Object.keys(grouped).forEach(date => {
    if (grouped[date].length > 0) {
      filteredGrouped[date] = grouped[date];
    }
  });
  
  // 按日期排序
  const sortedDates = Object.keys(filteredGrouped).sort();
  const sortedGrouped = {};
  
  sortedDates.forEach(date => {
    sortedGrouped[date] = filteredGrouped[date];
    // 默认展开最近的日期
    if (date === sortedDates[sortedDates.length - 1]) {
      expandedDays.value.add(date);
    }
  });
  
  groupedTracksByDate.value = sortedGrouped;
  
  console.log('分组结果:', {
    总轨迹数: deviceTracks.value.length,
    有效日期数: sortedDates.length,
    分组详情: sortedGrouped
  });
};

const selectTrack = (track) => {
  selectedTrackId.value = track.id;
  selectedTrack.value = track;
};

const playTrack = () => {
  if (!selectedTrack.value || !selectedTrack.value.pathPoints) return;
  
  const positions = DataUtils.pathPointsToTrackPositions(selectedTrack.value.pathPoints);
  
  if (positions.length === 0) {
    console.warn("没有有效的轨迹点");
    return;
  }
  
  // 清除之前的轨迹实体
  stopTrack();
  
  // 使用提供的轨迹播放代码
  trackPlay(positions, null, null, 32, 32, selectedDevice.value.deviceName, loopPlay.value);
  
  isPlaying.value = true;
};

const stopTrack = () => {
  if (currentTrackEntity) {
    props.viewer.entities.remove(currentTrackEntity);
    currentTrackEntity = null;
  }
  props.viewer.clock.shouldAnimate = false;
  isPlaying.value = false;
};

// 计算轨迹统计数据
const calculateTrackStatistics = (track) => {
  if (!track.pathPoints || track.pathPoints.length < 2) {
    return {
      totalDistance: 0,
      totalDuration: 0,
      totalArea: 0
    };
  }
  
  const pathPoints = track.pathPoints;
  let totalDistance = 0;
  let totalDuration = 0;
  let totalArea = 0;
  
  // 设备作业宽度（米），根据设备类型设定
  const workingWidth = getWorkingWidth(selectedDevice.value?.deviceType);
  
  // 计算距离和面积
  for (let i = 0; i < pathPoints.length - 1; i++) {
    const currentPoint = pathPoints[i];
    const nextPoint = pathPoints[i + 1];
    
    // 计算两点间距离
    const segmentDistance = DataUtils.calculateDistance(
      currentPoint.longitude,
      currentPoint.latitude,
      nextPoint.longitude,
      nextPoint.latitude
    );
    
    totalDistance += segmentDistance;
    
    // 计算作业面积（距离 × 作业宽度）
    totalArea += segmentDistance * workingWidth;
  }
  
  // 计算时间持续时间（秒）
  if (track.startTime && track.endTime) {
    const startTime = new Date(track.startTime);
    const endTime = new Date(track.endTime);
    totalDuration = (endTime - startTime) / 1000; // 转换为秒
  } else if (pathPoints.length >= 2) {
    // 如果没有时间信息，根据路径点数量估算
    // 假设平均速度 10 km/h
    const averageSpeed = 10 / 3.6; // m/s
    totalDuration = totalDistance / averageSpeed;
  }
  
  return {
    totalDistance: Math.round(totalDistance),
    totalDuration: Math.round(totalDuration),
    totalArea: Math.round(totalArea)
  };
};

// 根据设备类型获取作业宽度
const getWorkingWidth = (deviceType) => {
  const widthMap = {
    'TRACTOR': 3.0,      // 拖拉机作业宽度 3米
    'HARVESTER': 4.5,    // 收割机作业宽度 4.5米
    'SEEDER': 2.5,       // 播种机作业宽度 2.5米
    'SPRAYER': 12.0,     // 喷药机作业宽度 12米
    'default': 3.0       // 默认作业宽度 3米
  };
  return widthMap[deviceType] || widthMap.default;
};

// 在地图上显示所有轨迹路径
const displayTracksOnMap = () => {
  // 清除之前的轨迹显示
  clearTrackDisplay();
  
  if (!deviceTracks.value || deviceTracks.value.length === 0) {
    return;
  }
  
  deviceTracks.value.forEach((track, index) => {
    if (!track.pathPoints || track.pathPoints.length === 0) {
      return;
    }
    
    // 转换轨迹点为 Cesium 位置
    const positions = track.pathPoints.map(point => 
      Cesium.Cartesian3.fromDegrees(point.longitude, point.latitude, 1)
    );
    
    if (positions.length < 2) {
      return;
    }
    
    // 创建轨迹线
    const trackEntity = props.viewer.entities.add({
      id: `track_line_${track.id}`,
      name: `轨迹线_${track.pathName || track.id}`,
      polyline: {
        positions: positions,
        width: 3,
        material: Cesium.Color.fromCssColorString('#00ff00'),
        clampToGround: true,
        show: true
      }
    });
    
    trackPathEntities.push(trackEntity);
    
    // 添加轨迹起点和终点标记
    const startPoint = props.viewer.entities.add({
      id: `track_start_${track.id}`,
      name: `起点_${track.pathName || track.id}`,
      position: positions[0],
      billboard: {
        image: '/images/start-flag.svg',
        width: 24,
        height: 24,
        heightReference: Cesium.HeightReference.CLAMP_TO_GROUND
      },
      label: {
        text: '起点',
        font: '12px sans-serif',
        fillColor: Cesium.Color.WHITE,
        outlineColor: Cesium.Color.BLACK,
        outlineWidth: 2,
        style: Cesium.LabelStyle.FILL_AND_OUTLINE,
        pixelOffset: new Cesium.Cartesian2(0, -30),
        heightReference: Cesium.HeightReference.CLAMP_TO_GROUND
      }
    });
    
    const endPoint = props.viewer.entities.add({
      id: `track_end_${track.id}`,
      name: `终点_${track.pathName || track.id}`,
      position: positions[positions.length - 1],
      billboard: {
        image: '/images/end-flag.svg',
        width: 24,
        height: 24,
        heightReference: Cesium.HeightReference.CLAMP_TO_GROUND
      },
      label: {
        text: '终点',
        font: '12px sans-serif',
        fillColor: Cesium.Color.WHITE,
        outlineColor: Cesium.Color.BLACK,
        outlineWidth: 2,
        style: Cesium.LabelStyle.FILL_AND_OUTLINE,
        pixelOffset: new Cesium.Cartesian2(0, -30),
        heightReference: Cesium.HeightReference.CLAMP_TO_GROUND
      }
    });
    
    trackPathEntities.push(startPoint, endPoint);
  });
  
  // 计算和显示运动覆盖面积
  calculateAndDisplayWorkingArea();
  
  // 定位到轨迹区域
  if (trackPathEntities.length > 0) {
    props.viewer.flyTo(trackPathEntities[0]);
  }
};

// 计算和显示设备运动覆盖的面积
const calculateAndDisplayWorkingArea = () => {
  if (!deviceTracks.value || deviceTracks.value.length === 0) {
    return;
  }
  
  // 获取所有轨迹点
  const allTrackPositions = [];
  deviceTracks.value.forEach(track => {
    if (track.pathPoints && track.pathPoints.length > 0) {
      track.pathPoints.forEach(point => {
        allTrackPositions.push(
          Cesium.Cartesian3.fromDegrees(point.longitude, point.latitude, 1)
        );
      });
    }
  });
  
  if (allTrackPositions.length < 3) {
    console.warn('轨迹点不足，无法计算面积');
    return;
  }
  
  // 使用凸包算法计算运动覆盖区域
  const workingAreaPositions = calculateConvexHull(allTrackPositions);
  
  if (workingAreaPositions.length >= 3) {
    // 计算面积
    const area = SpatialUtils.calculatePolygonArea(workingAreaPositions);
    
    // 在地图上显示覆盖面积
    workingAreaEntity = props.viewer.entities.add({
      id: 'working_area_' + selectedDevice.value.id,
      name: `运动覆盖区域 - ${DataUtils.formatDistance(Math.sqrt(area))}`,
      polygon: {
        hierarchy: new Cesium.PolygonHierarchy(workingAreaPositions),
        material: Cesium.Color.YELLOW.withAlpha(0.3),
        outline: true,
        outlineColor: Cesium.Color.ORANGE,
        height: 0,
        heightReference: Cesium.HeightReference.CLAMP_TO_GROUND
      },
      label: {
        text: `覆盖面积: ${(area / 10000).toFixed(2)}公顷`,
        font: '14px sans-serif',
        fillColor: Cesium.Color.YELLOW,
        outlineColor: Cesium.Color.BLACK,
        outlineWidth: 2,
        style: Cesium.LabelStyle.FILL_AND_OUTLINE,
        pixelOffset: new Cesium.Cartesian2(0, -50),
        heightReference: Cesium.HeightReference.CLAMP_TO_GROUND
      }
    });
    
    console.log(`设备运动覆盖面积: ${(area / 10000).toFixed(2)}公顷`);
  }
};

// 简化的凸包算法（Graham Scan）
const calculateConvexHull = (points) => {
  if (points.length < 3) return points;
  
  // 转换为经纬度坐标
  const cartographicPoints = points.map(point => {
    const cartographic = Cesium.Cartographic.fromCartesian(point);
    return {
      longitude: Cesium.Math.toDegrees(cartographic.longitude),
      latitude: Cesium.Math.toDegrees(cartographic.latitude),
      original: point
    };
  });
  
  // 找到最左下角的点
  let start = cartographicPoints[0];
  for (let i = 1; i < cartographicPoints.length; i++) {
    const p = cartographicPoints[i];
    if (p.latitude < start.latitude || 
        (p.latitude === start.latitude && p.longitude < start.longitude)) {
      start = p;
    }
  }
  
  // 简化的处理：只取边界点
  const minLon = Math.min(...cartographicPoints.map(p => p.longitude));
  const maxLon = Math.max(...cartographicPoints.map(p => p.longitude));
  const minLat = Math.min(...cartographicPoints.map(p => p.latitude));
  const maxLat = Math.max(...cartographicPoints.map(p => p.latitude));
  
  // 创建边界矩形
  const boundingBox = [
    Cesium.Cartesian3.fromDegrees(minLon, minLat, 1),
    Cesium.Cartesian3.fromDegrees(maxLon, minLat, 1),
    Cesium.Cartesian3.fromDegrees(maxLon, maxLat, 1),
    Cesium.Cartesian3.fromDegrees(minLon, maxLat, 1)
  ];
  
  return boundingBox;
};

// 清除轨迹显示
const clearTrackDisplay = () => {
  // 清除轨迹线和标记
  trackPathEntities.forEach(entity => {
    props.viewer.entities.remove(entity);
  });
  trackPathEntities.length = 0;
  
  // 清除覆盖面积
  if (workingAreaEntity) {
    props.viewer.entities.remove(workingAreaEntity);
    workingAreaEntity = null;
  }
};

// 轨迹播放函数（基于提供的代码）
const trackPlay = (positions = [], startIcon, endIcon, iconWidth = 32, iconHeight = 32, name = '', isLoop = false) => {
  if (positions.length === 0) {
    console.warn("请先绘制路径");
    return;
  }

  const speed = 12; // 控制速度

  // 创建一个 SampledPositionProperty 实例
  const sampledPosition = new Cesium.SampledPositionProperty();
  const startTime = Cesium.JulianDate.now();

  // 将positions转换为Cesium.Cartesian3格式
  const cartesianPositions = positions.map(pos => 
    Cesium.Cartesian3.fromDegrees(pos.x, pos.y, pos.z || 1)
  );

  // 添加样本点
  cartesianPositions.forEach((position, index) => {
    const time = Cesium.JulianDate.addSeconds(
      startTime,
      index * speed, // 每个点间隔speed秒
      new Cesium.JulianDate()
    );
    sampledPosition.addSample(time, position);
  });

  // 创建模型实体
  currentTrackEntity = props.viewer.entities.add({
    id: 'devicePath_' + selectedDevice.value.id,
    name: "运动路径",
    position: sampledPosition,
    orientation: new Cesium.VelocityOrientationProperty(sampledPosition),
    billboard: {
      image: '/images/tractor.svg', // 农机图标
      width: iconWidth,
      height: iconHeight,
      heightReference: Cesium.HeightReference.CLAMP_TO_GROUND
    },
    label: {
      text: name,
      show: true,
      font: `14px sans-serif`,
      fillColor: Cesium.Color.fromCssColorString('#fff'),
      pixelOffset: new Cesium.Cartesian2(0, -63),
      style: Cesium.LabelStyle.FILL,
      horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
      heightReference: Cesium.HeightReference.CLAMP_TO_GROUND
    },
    path: {
      leadTime: 0,
      trailTime: speed * (positions.length - 1),
      material: new Cesium.PolylineOutlineMaterialProperty({
        color: Cesium.Color.fromCssColorString('rgb(19, 95, 145)'),
        outlineColor: Cesium.Color.fromCssColorString('rgba(38, 158, 238, 1)'),
        outlineWidth: 2,
      }),
      resolution: 160,
      width: 4,
    }
  });

  // 设置时钟范围
  props.viewer.clock.startTime = startTime;
  props.viewer.clock.stopTime = Cesium.JulianDate.addSeconds(
    startTime,
    speed * (positions.length - 1),
    new Cesium.JulianDate()
  );
  props.viewer.clock.currentTime = startTime;
  props.viewer.clock.clockRange = isLoop ? Cesium.ClockRange.LOOP_STOP : Cesium.ClockRange.CLAMPED;
  props.viewer.clock.shouldAnimate = true;

  // 定位到轨迹
  props.viewer.flyTo(currentTrackEntity);
};

const updateDeviceEntities = () => {
  // 清除旧的设备实体
  deviceEntities.forEach(entity => props.viewer.entities.remove(entity));
  deviceEntities.clear();
  
  // 添加新的设备实体
  devices.value.forEach(device => {
    if (!device.currentPosition) return;
    
    const position = DataUtils.pointToCartesian3(device.currentPosition);
    if (!position) return;
    
    const entity = props.viewer.entities.add({
      id: 'device_' + device.id,
      name: device.deviceName,
      position: position,
      billboard: {
        image: getDeviceIcon(device.deviceType),
        width: 32,
        height: 32,
        color: DataUtils.getDeviceStatusColor(device.status),
        heightReference: Cesium.HeightReference.CLAMP_TO_GROUND
      },
      label: {
        text: device.deviceName,
        font: '12px sans-serif',
        fillColor: Cesium.Color.WHITE,
        outlineColor: Cesium.Color.BLACK,
        outlineWidth: 2,
        style: Cesium.LabelStyle.FILL_AND_OUTLINE,
        pixelOffset: new Cesium.Cartesian2(0, -40),
        heightReference: Cesium.HeightReference.CLAMP_TO_GROUND
      }
    });
    
    deviceEntities.set(device.id, entity);
  });
};

const getDeviceIcon = (deviceType) => {
  const iconMap = {
    'TRACTOR': '/images/tractor.svg',
    'HARVESTER': '/images/harvester.svg',
    'default': '/images/device.svg'
  };
  return iconMap[deviceType] || iconMap.default;
};

// 生命周期
onMounted(() => {
  refreshDevices();
});

// 对外暴露方法
defineExpose({
  refreshDevices,
  updateDeviceEntities
});
</script>

<style scoped>
.device-manager {
  position: relative;
  z-index: 1000;
}

.device-panel {
  position: absolute;
  top: 10px;
  left: 10px;
  width: 320px;
  background: rgba(0, 0, 0, 0.8);
  color: white;
  border-radius: 8px;
  transition: all 0.3s ease;
}

.device-panel.collapsed {
  width: 120px;
}

.panel-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 10px 15px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.2);
}

.panel-header h3 {
  margin: 0;
  font-size: 16px;
}

.collapse-btn {
  background: transparent;
  border: 1px solid rgba(255, 255, 255, 0.3);
  color: white;
  padding: 4px 8px;
  border-radius: 4px;
  cursor: pointer;
  font-size: 12px;
}

.collapse-btn:hover {
  background: rgba(255, 255, 255, 0.1);
}

.panel-content {
  padding: 15px;
  max-height: 70vh;
  overflow-y: auto;
}

.filter-section {
  margin-bottom: 15px;
  display: flex;
  align-items: center;
  gap: 10px;
}

.filter-section label {
  font-size: 12px;
  white-space: nowrap;
}

.filter-section select {
  flex: 1;
  padding: 4px 8px;
  border: 1px solid #ccc;
  border-radius: 4px;
  background: white;
  color: black;
}

.refresh-btn {
  padding: 4px 12px;
  background: #007bff;
  color: white;
  border: none;
  border-radius: 4px;
  cursor: pointer;
  font-size: 12px;
}

.refresh-btn:hover {
  background: #0056b3;
}

.device-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.device-item {
  background: rgba(255, 255, 255, 0.1);
  border-radius: 6px;
  padding: 10px;
  cursor: pointer;
  transition: background 0.2s ease;
}

.device-item:hover {
  background: rgba(255, 255, 255, 0.2);
}

.device-item.selected {
  background: rgba(0, 123, 255, 0.3);
  border: 1px solid #007bff;
}

.device-info {
  margin-bottom: 8px;
}

.device-name {
  font-weight: bold;
  font-size: 14px;
  margin-bottom: 4px;
}

.device-type {
  font-size: 12px;
  color: #ccc;
  margin-bottom: 4px;
}

.device-status {
  font-size: 12px;
  padding: 2px 6px;
  border-radius: 3px;
  display: inline-block;
  margin-bottom: 4px;
}

.device-status.working {
  background: #28a745;
}

.device-status.idle {
  background: #ffc107;
  color: black;
}

.device-status.offline {
  background: #dc3545;
}

.device-time {
  font-size: 11px;
  color: #999;
}

.device-actions {
  display: flex;
  gap: 8px;
}

.action-btn {
  flex: 1;
  padding: 4px 8px;
  background: #17a2b8;
  color: white;
  border: none;
  border-radius: 4px;
  cursor: pointer;
  font-size: 12px;
}

.action-btn:hover {
  background: #138496;
}

.track-control {
  position: absolute;
  top: 10px;
  right: 110px;
  width: 400px;
  background: rgba(0, 0, 0, 0.8);
  color: white;
  border-radius: 8px;
}

.control-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 10px 15px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.2);
}

.control-header h4 {
  margin: 0;
  font-size: 14px;
}

.close-btn {
  background: transparent;
  border: none;
  color: white;
  font-size: 18px;
  cursor: pointer;
  padding: 0;
  width: 24px;
  height: 24px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.close-btn:hover {
  background: rgba(255, 255, 255, 0.1);
  border-radius: 50%;
}

.control-content {
  padding: 15px;
  max-height: 60vh;
  overflow-y: auto;
}

.time-range {
  margin-bottom: 15px;
}

.time-inputs {
  margin-bottom: 10px;
}

.time-range label {
  display: block;
  margin-bottom: 5px;
  font-size: 12px;
}

.time-range input {
  width: 100%;
  padding: 6px 8px;
  margin-bottom: 10px;
  border: 1px solid #ccc;
  border-radius: 4px;
  background: white;
  color: black;
}

.time-actions {
  display: flex;
  gap: 8px;
}

.reset-btn {
  flex: 1;
  padding: 8px;
  background: #6c757d;
  color: white;
  border: none;
  border-radius: 4px;
  cursor: pointer;
  font-size: 12px;
}

.reset-btn:hover {
  background: #5a6268;
}

.query-btn {
  flex: 2;
  padding: 8px;
  background: #28a745;
  color: white;
  border: none;
  border-radius: 4px;
  cursor: pointer;
  font-size: 12px;
}

.query-btn:hover {
  background: #218838;
}

.track-list {
  margin-bottom: 15px;
  max-height: 200px;
  overflow-y: auto;
}

.track-item {
  background: rgba(255, 255, 255, 0.1);
  border-radius: 4px;
  padding: 8px;
  margin-bottom: 8px;
  cursor: pointer;
  transition: background 0.2s ease;
}

.track-item:hover {
  background: rgba(255, 255, 255, 0.2);
}

.track-item.selected {
  background: rgba(0, 123, 255, 0.3);
  border: 1px solid #007bff;
}

.track-name {
  font-weight: bold;
  font-size: 13px;
  margin-bottom: 4px;
}

.track-info {
  font-size: 11px;
  color: #ccc;
  display: flex;
  justify-content: space-between;
}

.play-controls {
  display: flex;
  gap: 10px;
  align-items: center;
}

.play-btn, .stop-btn {
  flex: 1;
  padding: 8px;
  border: none;
  border-radius: 4px;
  cursor: pointer;
  font-size: 12px;
}

.play-btn {
  background: #007bff;
  color: white;
}

.play-btn:hover:not(:disabled) {
  background: #0056b3;
}

.play-btn:disabled {
  background: #6c757d;
  cursor: not-allowed;
}

.stop-btn {
  background: #dc3545;
  color: white;
}

.stop-btn:hover {
  background: #c82333;
}

.play-controls label {
  font-size: 12px;
  display: flex;
  align-items: center;
  gap: 4px;
  white-space: nowrap;
}

/* 多日轨迹分组样式 */
.day-group {
  margin-bottom: 8px;
}

.day-header {
  background: rgba(255, 255, 255, 0.15);
  padding: 8px 12px;
  border-radius: 4px;
  cursor: pointer;
  display: flex;
  justify-content: space-between;
  align-items: center;
  transition: background 0.2s ease;
  border-left: 3px solid #007bff;
}

.day-header:hover {
  background: rgba(255, 255, 255, 0.25);
}

.day-header.expanded {
  background: rgba(0, 123, 255, 0.2);
  border-left-color: #28a745;
}

.date-label {
  font-weight: bold;
  font-size: 13px;
}

.track-count {
  font-size: 11px;
  color: #ccc;
}

.expand-icon {
  font-size: 12px;
  transition: transform 0.2s ease;
}

.day-tracks {
  margin-top: 8px;
  padding-left: 12px;
  border-left: 2px solid rgba(255, 255, 255, 0.1);
}

.day-tracks .track-item {
  margin-bottom: 6px;
  background: rgba(255, 255, 255, 0.08);
}

.day-tracks .track-item:hover {
  background: rgba(255, 255, 255, 0.15);
}

.day-tracks .track-item.selected {
  background: rgba(0, 123, 255, 0.25);
  border: 1px solid #007bff;
}

/* 无轨迹数据提示样式 */
.no-tracks-message {
  text-align: center;
  padding: 20px;
  color: #ccc;
  font-size: 12px;
  background: rgba(255, 255, 255, 0.05);
  border-radius: 4px;
  border: 1px dashed rgba(255, 255, 255, 0.2);
}
</style>